﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using ProyectoBizarro.Persistencia;
using ProyectoBizarro.Dominio;
using ProyectoBizarro.Excepciones;
using System.Net;
using System.Messaging;


namespace ProyectoBizarro
{

    public class Productos : IProductos
    {

        private ProductoDAO productoDAO = null;
        private ProductoDAO ProductoDAO
        {
            get
            {
                if (productoDAO == null)
                    productoDAO = new ProductoDAO();
                return productoDAO;
            }

        }

        private UsuarioDAO usuarioDAO = null;
        private UsuarioDAO UsuarioDAO
        {
            get
            {
                if (usuarioDAO == null)
                    usuarioDAO = new UsuarioDAO();
                return usuarioDAO;
            }

        }

        private MarcaDAO marcaDAO = null;
        private MarcaDAO MarcaDAO
        {
            get
            {
                if (marcaDAO == null)
                    marcaDAO = new MarcaDAO();
                return marcaDAO;
            }

        }

        private TipoProductoDAO tipoproductoDAO = null;
        private TipoProductoDAO TipoProductoDAO
        {
            get
            {
                if (tipoproductoDAO == null)
                    tipoproductoDAO = new TipoProductoDAO();
                return tipoproductoDAO;
            }

        }

        public Producto CrearProducto(DateTime creacion, int usuario, int estado, string ean, string denominacion, int marca, string medida, string descripcion, int tipo)
        {
            string rutaCola = @".\private$\productosoffline";
            if (!MessageQueue.Exists(rutaCola))
            {
                MessageQueue.Create(rutaCola);
                MessageQueue cola = new MessageQueue(rutaCola);

                Message mensaje = new Message();
                mensaje.Label = "Nueva Producto1";
                mensaje.Body = new Producto() { Codigo = 01001, Creacion = DateTime.Parse("04/10/2013"), Usuario = UsuarioDAO.Obtener(1), Estado = 0, EAN = "11111111", Denominacion = "Producto Offline1", Marca = MarcaDAO.Obtener(2), Medida = "un", Descripcion = "Añadido desde cola1", Tipo = TipoProductoDAO.Obtener(100) };
                cola.Send(mensaje);
                Message mensaje2 = new Message();
                mensaje2.Label = "Nueva Producto2";
                mensaje2.Body = new Producto() { Codigo = 01002, Creacion = DateTime.Parse("04/10/2013"), Usuario = UsuarioDAO.Obtener(1), Estado = 0, EAN = "22222222", Denominacion = "Producto Offline2", Marca = MarcaDAO.Obtener(2), Medida = "un", Descripcion = "Añadido desde cola2", Tipo = TipoProductoDAO.Obtener(110) };
                cola.Send(mensaje2);
            }
                

            int VerificarProductoXEan = ProductoDAO.VerificarProductoXEan(ean);
            int VerificarProductoXDenominacion = ProductoDAO.VerificarProductoXDenominacion(denominacion);

            if (VerificarProductoXEan == 1)
            {
                throw new FaultException<ValidationException>(new ValidationException() { ValidationError = "Ingreso Fallido" },
                    new FaultReason("Ingreso Fallido: Codigo EAN Existente"));
            }
            else
                if (VerificarProductoXDenominacion == 1)
                {
                    throw new FaultException<ValidationException>(new ValidationException() { ValidationError = "Ingreso Fallido" },
                        new FaultReason("Ingreso Fallido: Denominacion de Producto Existente"));
                }
                else
                {
                    Usuario usuarioExistente = UsuarioDAO.Obtener(usuario);
                    Marca marcaExistente = MarcaDAO.Obtener(marca);
                    TipoProducto tipoproductoExistente = TipoProductoDAO.Obtener(tipo);

                    Producto productoACrear = new Producto()
                    {
                        Creacion = creacion,
                        Usuario = usuarioExistente,
                        Estado = estado,
                        EAN = ean,
                        Denominacion = denominacion,
                        Marca = marcaExistente,
                        Medida = medida,
                        Descripcion = descripcion,
                        Tipo = tipoproductoExistente
                    };

                    return ProductoDAO.Crear(productoACrear);
                }
        }

        public Producto ObtenerProducto(int codigo)
        {
            return ProductoDAO.Obtener(codigo);
        }

        public Producto ModificarProducto(int codigo, DateTime creacion, int usuario, int estado, string ean, string denominacion, int marca, string medida, string descripcion, int tipo)
        {
            int VerificarProductoXEan = ProductoDAO.VerificarProductoXEan(ean);
            int VerificarProductoXDenominacion = ProductoDAO.VerificarProductoXDenominacion(denominacion);

            if(ProductoDAO.VerificarProductoXEanRegresaCod(ean)==codigo)
                VerificarProductoXEan = 0;
            if (ProductoDAO.VerificarProductoXDenominacionRegresaCod(denominacion) == codigo)
                VerificarProductoXDenominacion = 0;

            if (VerificarProductoXEan == 1)
            {
                throw new FaultException<ValidationException>(new ValidationException() { ValidationError = "Edicion Fallida" },
                    new FaultReason("Edicion Fallida: Codigo EAN Existente"));
            }
            else
                if (VerificarProductoXDenominacion == 1)
                {
                    throw new FaultException<ValidationException>(new ValidationException() { ValidationError = "Ingreso Fallido" },
                        new FaultReason("Ingreso Fallido: Denominacion de Producto Existente"));
                }
                else
                {
                    Usuario usuarioExistente = UsuarioDAO.Obtener(usuario);
                    Marca marcaExistente = MarcaDAO.Obtener(marca);
                    TipoProducto tipoproductoExistente = TipoProductoDAO.Obtener(tipo);

                    Producto productoAModificar = new Producto()
                    {
                        Codigo = codigo,
                        Creacion = creacion,
                        Usuario = usuarioExistente,
                        Estado = estado,
                        EAN = ean,
                        Denominacion = denominacion,
                        Marca = marcaExistente,
                        Medida = medida,
                        Descripcion = descripcion,
                        Tipo = tipoproductoExistente
                    };
                    return ProductoDAO.Modificar(productoAModificar);
                }
        }

        //public Producto EliminarProducto(int codigo)
        public void EliminarProducto(int codigo)
        {
            string rutaCola = @".\private$\productosoffline";
            if (MessageQueue.Exists(rutaCola))
            {
                MessageQueue cola = new MessageQueue(rutaCola);
                cola.Formatter = new XmlMessageFormatter(new Type[] { typeof(Producto) });
                Message mensaje = cola.Receive();
                Producto offline1 = (Producto)mensaje.Body;
                Message mensaje2 = cola.Receive();
                Producto offline2 = (Producto)mensaje2.Body;
                //Message mensaje3 = cola.Receive();
                //Producto offline3 = (Producto)mensaje3.Body;

                Producto ProductoCreada1 = CrearProducto(offline1.Creacion, offline1.Usuario.Codigo, offline1.Estado, offline1.EAN, offline1.Denominacion, offline1.Marca.Codigo, offline1.Medida, offline1.Descripcion, offline1.Tipo.Codigo);
                Producto ProductoCreada2 = CrearProducto(offline2.Creacion, offline2.Usuario.Codigo, offline2.Estado, offline2.EAN, offline2.Denominacion, offline2.Marca.Codigo, offline2.Medida, offline2.Descripcion, offline2.Tipo.Codigo);
                //Producto ProductoCreada3 = CrearProducto(offline2.Creacion, offline3.Usuario.Codigo, offline3.Estado, offline3.EAN, offline3.Denominacion, offline3.Marca.Codigo, offline3.Medida, offline3.Descripcion, offline3.Tipo.Codigo);
            }   

            Producto productoExistente = ProductoDAO.Obtener(codigo);

            /*Producto productoAEliminar = new Producto()
            {
                Codigo = codigo,
                Creacion = productoExistente.Creacion,
                Usuario = productoExistente.Usuario,
                Estado = 1,
                EAN = productoExistente.EAN,
                Denominacion = productoExistente.Denominacion,
                Marca = productoExistente.Marca,
                Medida = productoExistente.Medida,
                Descripcion = productoExistente.Descripcion,
                Tipo = productoExistente.Tipo
            };

            return ProductoDAO.Modificar(productoAEliminar);
            */
            ProductoDAO.Eliminar(productoExistente);
        }

        public List<Producto> ListarProducto()
        {
            return ProductoDAO.ListarTodos().ToList();
        }

        public List<Marca> ListarMarca()
        {
            return MarcaDAO.ListarTodos().ToList();
        }

        public List<TipoProducto> ListarTipoProducto()
        {
            return TipoProductoDAO.ListarTodos().ToList();
        }

        public List<Usuario> ListarUsuario()
        {
            return UsuarioDAO.ListarTodos().ToList();
        }

    }
}
